﻿import wx
import requests
import json
import os
from datetime import datetime
from configparser import ConfigParser

class WeatherApp(wx.Frame):
    def __init__(self, *args, **kw):
        super(WeatherApp, self).__init__(*args, **kw)

        self.selected_date_index = 0  # 当前选择的日期索引
        self.weather_data = []  # 存储天气数据
        self.config_file = 'config.ini'  # 配置文件名

        # 创建面板和垂直布局
        panel = wx.Panel(self)
        vbox = wx.BoxSizer(wx.VERTICAL)

        # 创建城市搜索框
        self.city_search = wx.TextCtrl(panel, style=wx.TE_PROCESS_ENTER)
        self.city_search.SetHint("搜索城市...")  # 设置提示文本
        vbox.Add(self.city_search, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)

        # 创建城市选择框
        self.city_choice = wx.Choice(panel, choices=self.load_city_list())
        self.load_last_search()  # 加载最后查找的城市
        vbox.Add(self.city_choice, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)

        # 创建水平布局以放置天气信息框和按钮
        hbox = wx.BoxSizer(wx.HORIZONTAL)

        # 创建按钮
        self.prev_day_button = wx.Button(panel, label="上一天")
        self.next_day_button = wx.Button(panel, label="下一天")
        hbox.Add(self.prev_day_button, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)

        # 创建文本框用于显示天气信息（固定大小）
        self.weather_info = wx.TextCtrl(panel, style=wx.TE_MULTILINE | wx.TE_READONLY | wx.HSCROLL, size=(300, 140))
        hbox.Add(self.weather_info, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)

        hbox.Add(self.next_day_button, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)

        vbox.Add(hbox, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)

        # 创建获取天气按钮
        self.get_weather_button = wx.Button(panel, label="获取天气")
        vbox.Add(self.get_weather_button, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)

        # 添加作者标注
        self.author_label = wx.StaticText(panel, label="作者: LGCR837", style=wx.ALIGN_CENTER)
        self.author_label.SetForegroundColour(wx.Colour(169, 169, 169))  # 设置灰色
        vbox.Add(self.author_label, proportion=0, flag=wx.ALIGN_CENTER | wx.ALL, border=10)

        panel.SetSizer(vbox)

        # 设置窗口的最小和最大尺寸
        self.SetMinSize(self.GetSize())
        self.SetMaxSize(self.GetSize())

        # 设置按钮的事件处理
        self.get_weather_button.Bind(wx.EVT_BUTTON, self.on_get_weather)
        self.prev_day_button.Bind(wx.EVT_BUTTON, self.on_prev_day)
        self.next_day_button.Bind(wx.EVT_BUTTON, self.on_next_day)

        # 设置文本框输入事件处理
        self.city_search.Bind(wx.EVT_TEXT, self.on_search_city)

        # 添加窗口标题和大小
        self.SetTitle("SeeWeather")
        self.SetSize((500, 400))

    def load_city_list(self):
        """加载城市列表"""
        try:
            with open('citycode.json', 'r', encoding='utf-8') as file:
                city_data = json.load(file)
                cities = [city['city_name'] for city in city_data]
                self.city_data = city_data  # 保存城市数据
                return cities
        except Exception as e:
            wx.MessageBox(f"加载城市列表失败: {e}", "错误", wx.ICON_ERROR)
            return []

    def load_last_search(self):
        """加载最后查找的城市"""
        config = ConfigParser()
        if os.path.exists(self.config_file):
            config.read(self.config_file)
            last_city = config.get('Weather', 'last_city', fallback='')
            if last_city in self.city_choice.GetItems():
                self.city_choice.SetStringSelection(last_city)

    def save_last_search(self, city_name):
        """保存最后查找的城市到配置文件"""
        config = ConfigParser()
        config['Weather'] = {'last_city': city_name}
        with open(self.config_file, 'w') as configfile:
            config.write(configfile)

    def on_get_weather(self, event):
        try:
            # 获取选择的城市
            selected_city_name = self.city_choice.GetStringSelection()
            if not selected_city_name:
                wx.MessageBox("请选择一个城市", "错误", wx.ICON_ERROR)
                return

            # 保存最后查找的城市
            self.save_last_search(selected_city_name)

            # 获取城市编码
            city_code = next((city['city_code'] for city in self.city_data if city['city_name'] == selected_city_name), None)
            if not city_code:
                wx.MessageBox("未找到城市编码", "错误", wx.ICON_ERROR)
                return

            # 检查本地缓存，如果今天的数据存在，则使用它
            today_date = self.get_today_date()
            cached_weather = self.load_local_weather(city_code, today_date)
            if cached_weather:
                self.weather_data = cached_weather.get("forecast", [])
                self.selected_date_index = 0  # 重置索引
                self.display_weather_info()
            else:
                # 否则请求最新天气数据
                self.fetch_weather_data(city_code, selected_city_name)

        except Exception as e:
            wx.MessageBox(f"获取天气失败: {e}", "错误", wx.ICON_ERROR)

    def load_local_weather(self, city_code, date):
        """加载本地天气数据"""
        local_file = f"./history/{city_code}_{date}.json"
        if os.path.exists(local_file):
            with open(local_file, 'r', encoding='utf-8') as file:
                return json.load(file)
        return None

    def fetch_weather_data(self, city_code, city_name):
        """联网获取天气数据并保存到本地"""
        url = f"http://t.weather.itboy.net/api/weather/city/{city_code}"
        response = requests.get(url)
        
        if response.status_code == 200:
            data = response.json()
            self.weather_data = data['data']['forecast']  # 保存所有天气数据
            self.save_weather_data(city_code, data['data'], self.get_today_date())  # 保存天气数据
            self.selected_date_index = 0  # 重置索引
            self.display_weather_info()
        else:
            wx.MessageBox("获取天气数据失败", "错误", wx.ICON_ERROR)

    def display_weather_info(self):
        """显示当前选择的天气信息"""
        if not self.weather_data:
            return

        forecast = self.weather_data[self.selected_date_index]
        weather_info_text = (f"日期: {forecast['ymd']}\n"
                              f"城市: {forecast['date']} {forecast['week']}\n"
                              f"温度: {forecast['low']} - {forecast['high']}\n"
                              f"天气: {forecast['type']}\n"
                              f"风速: {forecast['fx']}, 风力: {forecast['fl']}\n"
                              f"提醒: {forecast['notice']}")
        self.weather_info.SetValue(weather_info_text)

    def save_weather_data(self, city_code, weather_data, date):
        """保存天气数据到本地"""
        local_file = f"./history/{city_code}_{date}.json"
        # 如果历史目录不存在则创建
        os.makedirs('./history', exist_ok=True)

        with open(local_file, 'w', encoding='utf-8') as file:
            json.dump(weather_data, file, ensure_ascii=False, indent=4)

    def on_prev_day(self, event):
        """切换到前一天的天气"""
        if self.selected_date_index > 0:
            self.selected_date_index -= 1
            self.display_weather_info()
        else:
            wx.MessageBox("已是第一天", "提示", wx.ICON_INFORMATION)

    def on_next_day(self, event):
        """切换到下一天的天气"""
        if self.selected_date_index < len(self.weather_data) - 1:
            self.selected_date_index += 1
            self.display_weather_info()
        else:
            wx.MessageBox("已是最后一天", "提示", wx.ICON_INFORMATION)

    def on_search_city(self, event):
        """根据输入内容动态筛选城市"""
        search_text = self.city_search.GetValue().lower()
        filtered_cities = [city['city_name'] for city in self.city_data if search_text in city['city_name'].lower()]
        self.city_choice.Set(filtered_cities)

    def get_today_date(self):
        """获取今天的日期，格式为 yyyy-mm-dd"""
        return datetime.now().strftime('%Y-%m-%d')

if __name__ == "__main__":
    app = wx.App(False)
    frame = WeatherApp(None, title="天气查询", size=(500, 400))
    frame.Show()
    app.MainLoop()